package com.starleague.battletech.unit.jpa.appengine;

import java.util.Map;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToOne;

import com.starleague.battletech.unit.BattletechUnitMovementType;
import com.starleague.battletech.unit.HasMutableMovement;
import com.starleague.battletech.unit.IMutableBattletechUnit;
import com.starleague.battletech.unit.IMutablePilot;
import com.starleague.battletech.unit.IWeight;
import com.starleague.hexagonal.IHexCoordinate;
import com.starleague.hexagonal.jpa.appengine.HexCoordinateGae;
import com.starleague.jpa.appengine.GaeDao;

@MappedSuperclass
public abstract class BattletechUnitGae
        extends GaeDao
        // TODO: GaeDaoChild
        implements IMutableBattletechUnit, HasMutableMovement
{
    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private PilotGae pilot;

    @Basic(optional = false)
    @Column(nullable = false)
    @Embedded
    private WeightGae weight;

    @Embedded
    private HexCoordinateGae hexCoordinate;

    @Basic(optional = true)
    @Column(nullable = true)
    private int elevation;

    @Basic(optional = false)
    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private BattletechUnitMovementType movementType;

    @Basic(optional = false)
    @Column(nullable = false)
    private int usedMovementPoints;

    protected BattletechUnitGae(PilotGae pilot,
                                IWeight weight,
                                BattletechUnitMovementType movementType)
    {
        this.pilot = pilot;
        this.weight = new WeightGae(weight);
        this.movementType = movementType;
    }

    protected BattletechUnitGae()
    {
        //
    }

    @Override
    public PilotGae getPilot()
    {
        return this.pilot;
    }

    @Override
    public void setPilot(IMutablePilot pilot)
    {
        this.pilot = (PilotGae) pilot;
    }

    @Override
    public WeightGae getWeight()
    {
        return this.weight;
    }

    @Override
    public HexCoordinateGae getHexCoordinate()
    {
        return HexCoordinateGae.toNullable(this.hexCoordinate);
    }

    @Override
    public void setHexCoordinate(IHexCoordinate hexCoordinate)
    {
        this.hexCoordinate = HexCoordinateGae.fromNullable(hexCoordinate);
    }

    @Override
    public int getElevation()
    {
        return this.elevation;
    }

    @Override
    public void setElevation(int elevation)
    {
        this.elevation = elevation;
    }

    @Override
    public BattletechUnitMovementType getMovementType()
    {
        return this.movementType;
    }

    @Override
    public int getUsedMovementPoints()
    {
        return this.usedMovementPoints;
    }

    @Override
    public void setUsedMovementPoints(int usedMovementPoints)
    {
        this.usedMovementPoints = usedMovementPoints;
    }

    @Override
    public void clearMovement()
    {
        this.usedMovementPoints = 0;
    }

    @Override
    public Map<String, Object> infoProperties()
    {
        Map<String, Object> infoPropertyMap = super.infoProperties();
        infoPropertyMap.put("pilot", this.pilot);
        infoPropertyMap.put("weight", this.weight);
        infoPropertyMap.put("hexCoordinate", HexCoordinateGae.toNullable(this.hexCoordinate));
        infoPropertyMap.put("elevation", this.elevation);
        infoPropertyMap.put("movementType", this.movementType);
        infoPropertyMap.put("usedMovementPoints", this.usedMovementPoints);
        return infoPropertyMap;
    }
}
